/* ************************************************************************

   Copyright:

   License:

   Authors:

************************************************************************ */

/* ************************************************************************



************************************************************************ */

qx.Class.define("mmclient.ReferenceView",
{
  extend : qx.ui.container.Composite,


  /*
  *****************************************************************************
     CONSTRUCTOR
  *****************************************************************************
  */

  construct : function(vMapView)
  {
    this.base(arguments);

    // Configure layout
    var layout = new qx.ui.layout.Basic;
    this.setLayout(layout);
    this.setBackgroundColor("#FFFFFF");
    this.setMapView(vMapView);

    this._createRefPane();
  },




  /*
  *****************************************************************************
     PROPERTIES
  *****************************************************************************
  */

  properties :
  {
    /**
    * Image of reference map.
    *
    */
    refMapObj :
    {
      check : "Object",
      init : null
    },

    /**
    * Cell size of reference map.
    *
    */
    cellSize :
    {
      check : "Number",
      init : 0
    },

    /**
    * Cell size of reference box.
    *
    */
    boxCellSize :
    {
      check : "Number",
      init : 0
    },

    /**
    * Offset X.
    *
    */
    offsetX :
    {
      check : "Number",
      init : 0
    },

    /**
    * Offset Y.
    *
    */
    offsetY :
    {
      check : "Number",
      init : 0
    },

    /**
    * Dragging?
    *
    */
    dragging :
    {
      check : "Boolean",
      init : false
    },
    
    _box :
    {
      check : "Object",
      init : null
    },    
    
    /**
    * Map View
    *
    */
    mapView :
    {
      check : "Object",
      init : null
    },
    
    /**
    * Whether or not the control has been initialized
    */
    initialized :
    {
      check : "Boolean",
      init : false
    }
    
  },

  /*
  *****************************************************************************
     MEMBERS
  *****************************************************************************
  */

  members :
  {
    /**
     * TODOC
     *
     * @type member
     * @return {void} 
     */
    _createRefPane : function()
    {
      this._mapField = new qx.ui.basic.Image();
      this._mapField.setAllowShrinkX(true);
      this._mapField.setAllowShrinkY(true);
      
      this.add(this._mapField);
      
      this._drawField = new qx.ui.core.Widget().set({
        width : 200
      });
      
      this.add(this._drawField); 

      this._drawField.addListener("mousemove", function(e) {
        // Auto Resize------------------------------
        // Not perfect, will come back to this later.
        if (this.getInitialized())
        {
          var loc = this.getContentLocation("box");
          if (loc != null)
          {
            var w = loc["right"] - loc["left"];
            var h = loc["bottom"] - loc["top"];
            if (this.getRefMapObj().getWidth() != w || 
                this.getRefMapObj().getHeight() != h)
            {
              this.initialize();
            }
          }
        }
        //-----------------------------------------
      }, this); 

      this._box = new mmclient.cropper.CropperMod(this._drawField, 'move').set({
        cropActive        : true,
        cropType          : "full",
        cropMarginLeft    : 0,
        cropMarginRight   : 0,
        cropMarginTop     : 0,
        cropMarginBottom  : 0,
        cropPaddingLeft   : 0,
        cropPaddingRight  : 0,
        cropPaddingTop    : 0,
        cropPaddingBottom : 0
      });
      
      this._box.addListener('cropSelected', function(e) {
        if (this.getInitialized())
        {        
          var d = e.getData();
          var x1 = d.left;
          var y1 = d.top;
          var x2 = d.left + d.width;
          var y2 = d.top + d.height;
  
          this.applyReference(x1, y1, x2, y2);
        }
      },this);
    },

    /**
     * TODOC
     *
     * @type member
     * @return {void} 
     */
    changeImage : function(w, h, ext)
    {
      var rpc = new qx.io.remote.Rpc("http://localhost/services/", "qooxdoo.mmserv");
      rpc.setCrossDomain(true);
      rpc.setTimeout(10000);

      var self = this;
      var setMapImg = function(result, exc)
      {
        if (exc == null)
        {
          // alert("Result of async call: " + result);
          self._mapField.setSource("http://localhost" + result);
        }
        else
        {
          alert("Exception during async call: " + exc);
        }
        self._mapField.setUserBounds(0, 0, w, h); 
      };

      rpc.callAsync(setMapImg, "getMapImg",
      {
        doc_id : qx.core.Init.getApplication().getAppHistory().getState(),
        width  : w,
        height : h,
        minx   : ext.getMinX(),
        miny   : ext.getMinY(),
        maxx   : ext.getMaxX(),
        maxy   : ext.getMaxY()
      });
    },


    /**
     * TODOC
     *
     * @type member
     * @param w {var} TODOC
     * @param h {var} TODOC
     * @param ext {var} TODOC
     * @return {void} 
     */
    setDimension : function()
    {
      var loc = this.getContentLocation("box");
      var wdth = loc["right"] - loc["left"];
      var hght = loc["bottom"] - loc["top"];

      this.setCellSize(0);
      this.getRefMapObj().setWidth(wdth);
      this.getRefMapObj().setHeight(hght);
      this.getRefMapObj().setExtent(
        new mmclient.mapscript.RectObj(
          this.getMapView().getDefaultExtent().getMinX(),
          this.getMapView().getDefaultExtent().getMinY(),
          this.getMapView().getDefaultExtent().getMaxX(),
          this.getMapView().getDefaultExtent().getMaxY()
        )
      );
      
      var mw = this.getRefMapObj().getMap().getWidth();
      var mh = this.getRefMapObj().getMap().getHeight();
      var rw = this.getRefMapObj().getWidth();
      var rh = this.getRefMapObj().getHeight();
      var wratio = mw / rw;
      var hratio = mh / rh;

      var rbwidth, rbheight;

      if (wratio > hratio)
      {
        rbwidth = Math.round(rw);
        rbheight = Math.round(mh / wratio);
      }
      else if (hratio > wratio)
      {
        rbwidth = Math.round(mw / hratio);
        rbheight = Math.round(rh);
      }
      else
      {
        rbwidth = Math.round(rw);
        rbheight = Math.round(rh);
      }
      this.getRefMapObj().setWidth(rbwidth);
      this.getRefMapObj().setHeight(rbheight);
      this.setCellSize(
        this.getMapView()._adjustExtent(
          this.getRefMapObj().getExtent(), 
          this.getRefMapObj().getWidth(), 
          this.getRefMapObj().getHeight()
        )
      );

      this._drawField.setWidth(rbwidth);
      this._drawField.setHeight(rbheight);
      
      this.setOffsetX(this._drawField.getBounds().left);
      this.setOffsetY(this._drawField.getBounds().top);

      this.changeImage(rbwidth, rbheight, this.getRefMapObj().getExtent());
      this.drawRefBox(this.getRefMapObj().getMap().getExtent());
    },

    /**
     * TODOC
     *
     * @type member
     * @param extent {var} TODOC
     * @return {void} 
     */
    drawRefBox : function(extent)
    {
      var x1, y1, x2, y2;
      var x, y, w, h;
      var rw = this.getRefMapObj().getWidth();
      var rh = this.getRefMapObj().getHeight();

      if (this.getCellSize() == 0)
      {      
        this.setCellSize(
          this.getMapView()._adjustExtent(
            this.getRefMapObj().getExtent(), 
            this.getRefMapObj().getWidth(), 
            this.getRefMapObj().getHeight()
          )
        );
      }

      if (this.getCellSize() != 0)
      {
        x1 = extent.getMinX() / this.getCellSize()
        y1 = extent.getMinY() / this.getCellSize();
        x2 = extent.getMaxX() / this.getCellSize();
        y2 = extent.getMaxY() / this.getCellSize();
        
        w = Math.round(x2 - x1);
        h = Math.round(y2 - y1);
        x = Math.round((rw / 2) + x1);
        y = Math.round((rh / 2) - y1 - h);

// I have to check the x/y coords so
// the Cropper doesn't error out. It
// doesn't accept negative numbers in
// 'move' mode.
        if (x < 0) 
        {
          w += x;
          x = 0;
        }
        if (y < 0) 
        {
          h += y;
          y = 0;
        }

        this._box.drawRect(x, y, w, h);
      }
    },
    
    
    /* *****************
        FROM mapserv.js
       ***************** */
    
    /**
     * Calculate a new map extent to be centered on an image coordinate
     * from the reference map image, and store in the 
     * {@link mapmedley.mapscript.RectObj} (extent) field.
     *
     * @type member
     * @param x {Integer} Reference map image coordinate x value.
     * @param y {Integer} Reference map image coordinate y value.
     * @return {void} 
     */
    applyReference : function(x1, y1, x2, y2)
    {
      var minx;
      var miny;
      var maxx;
      var maxy;

      if (this.getRefMapObj().getMap().getCellSize() == 0) {
        this.getRefMapObj().getMap().setCellSize(
          this.getMapView()._adjustExtent(
            this.getRefMapObj().getMap().getExtent(), 
            this.getRefMapObj().getMap().getWidth(), 
            this.getRefMapObj().getMap().getHeight()
          )
        );
      }

      // Fix an alignment problem with the click-coords
      // Not sure what causes this. This code is through
      // trial and error. It seems that I don't need to
      // modify X for some reason??? Oh well, this is
      // good enough.
      var kx = 0;
      var ky = 0;
      if (this.getRefMapObj().getWidth() > this.getRefMapObj().getHeight())
      {
        kx = 0
        ky = 2;
      }
      else if (this.getRefMapObj().getWidth() < this.getRefMapObj().getHeight())
      {
        kx = 0;
        ky = 1;
      }

      minx = this.getRefMapObj().getExtent().getMinX() + this.getCellSize() * (x1-kx);
      miny = this.getRefMapObj().getExtent().getMaxY() - this.getCellSize() * (y2-ky);
      maxx = this.getRefMapObj().getExtent().getMinX() + this.getCellSize() * (x2-kx);
      maxy = this.getRefMapObj().getExtent().getMaxY() - this.getCellSize() * (y1-ky);

      var tmpExt = new mmclient.mapscript.RectObj(minx, miny, maxx, maxy);
      this.getRefMapObj().getMap().setExtent(tmpExt);
      this.getRefMapObj().getMap().setCellSize(
        this.getMapView()._adjustExtent(
          this.getRefMapObj().getMap().getExtent(), 
          this.getRefMapObj().getMap().getWidth(), 
          this.getRefMapObj().getMap().getHeight()
        )
      );

      this.getMapView().changeImage(
        this.getRefMapObj().getMap().getWidth(), 
        this.getRefMapObj().getMap().getHeight(), 
        this.getRefMapObj().getMap().getExtent()
      );
      this.drawRefBox(this.getRefMapObj().getMap().getExtent());
    },
    
    /* ****************
        END mapserv.js
       **************** */

    /**
     * TODOC
     *
     * @type member
     * @param mmdoc {State} Document to load
     * @return {void}
     */
    initialize : function()
    {
      this.debug("ReferenceView Initializing...");

      this.setRefMapObj(this.getMapView().getMapObj().getReferenceMap());
      this.getRefMapObj().setMap(this.getMapView().getMapObj());
      this.setDimension();
      this.setInitialized(true);
    }
  }
});
